<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2018/8/9
 * Time: 21:24
 */

namespace app\api\service;
use app\api\model\Order as OrderModel;
use app\api\service\Order as OrderService;
use app\lib\enum\OrderStatusEnum;
use app\lib\exception\OrderException;
use app\lib\exception\TokenException;
use think\Loader;

//引入支付文件
Loader::import('WxPay.WxPay', EXTEND_PATH, '.Api.php');
class Pay
{
    private $orderId;
    private $orderNo;
    public function __construct($orderId)
    {
        if(!$orderId)
        {
            throw new Exception('订单号不能为空！');
        }
        $this -> orderId = $orderId;
    }
    //1
    //支付方法
    public function pay()
    {
        //1.0定单号是否存在
        //2.0定单号和用户是否匹配
        //3.0定单是否己经付款
        $this -> checkOrderValidateid();
        //库存量检测
        $order = new OrderService();
        $status = $order -> checkOrderStock($this -> orderId);
        if(!$status['pass']) return $status;
        return $this -> makeWxPreOrder($status['orderPrice']);
    }
    //3
    //向微信发送请求发送下定单
    private function makeWxPreOrder($totalPrice)
    {
        //获取openid
        $openid = Token::getCurrentTokenVar('openid');
        if(!$openid) throw new TokenException();
        $wxOrderData = new \WxPayUnifiedOrder();
        $wxOrderData -> setOut_trade_no($this -> orderNo);
        $wxOrderData -> setTrade_type('JSAPI');
        $wxOrderData -> setTotal_fee($totalPrice * 100);
        $wxOrderData -> setBody('零食商贩');
        $wxOrderData -> setOpenid($openid);
        $wxOrderData -> setNotify_url(config('secure.pay_back_url'));//必须要配置回调的地址
        return $this -> getPaySignature($wxOrderData);
    }
    //4
    //微信生成预定单接口
    private function getPaySignature($wxOrderData)
    {
        $wxOrder = \WxPayApi::unifiedOrder($wxOrderData);
        if($wxOrder['return_code'] != 'SUCCESS' || $wxOrder['result_code'] != 'SUCCESS') {
            Log::recode($wxOrder, 'error');
            Log::recode('获取预定单接口！', 'error');
        };
        $this -> recoderPrepayId($wxOrder['prepay_id']);
        return $this -> sign($wxOrder);
    }

    //把模板消息的ID存到数据库里
    private function recoderPrepayId($prepay_id)
    {
        OrderModel::where(['id' => $this -> orderId]) -> update(['prepay_id' => $prepay_id]);
    }
    //2
    //检查定单是否合法
    public function checkOrderValidateid()
    {
        $order = OrderModel::get($this->orderId);
         if(!$order) throw new OrderException(['msg' => '定单不存在!']);
         if(!Token::checkValUid($order -> user_id)) throw new TokenException(['msg' => '订单和用户不匹配!', 'errorCode' => 10003]);
         if($order -> status != OrderStatusEnum::UNPAID) throw new OrderException(['定单状态异常!']);
         $this -> orderNo = $order -> order_no;
         return true;
    }
    //5
    //定义一个返回三个参数和签名的方法
    private function sign($wxOrder)
    {
        $jsApiPayData = new \WxPayJsApiPay();
        $jsApiPayData -> SetAppid(config('wx.app_id'));
        $jsApiPayData -> SetTimeStamp((String)time());//字符串形式的时间戳
        $rand = md5(time().mt_rand(0, 999));
        $jsApiPayData -> SetNonceStr($rand);//随机数
        $jsApiPayData -> SetPackage('prepay_id='.$wxOrder['prepay_id']);
        $jsApiPayData -> SetSignType('md5');//加密的主式
        $sign = $jsApiPayData -> MakeSign();//生成签名
        $rawValues = $jsApiPayData -> GetValues();//获取三个前端需要的参数
        $rawValues['sign'] = $sign;
        unset($rawValues['app_id']);//清除app_id为了保证安全
        return $rawValues;
    }
}